package cn.cjlmonster.hyouka_assistant.base

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.graphics.Rect
import android.os.Bundle
import android.util.Log
import android.view.ViewGroup.MarginLayoutParams
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.view.animation.DecelerateInterpolator
import android.webkit.WebView
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import cn.cjlmonster.hyouka_assistant.WKPlugin
import cn.cjlmonster.hyouka_assistant.ai.AIAssistantActivity.Companion.TAG
import cn.cjlmonster.hyouka_assistant.ai.evaluate
import cn.cjlmonster.hyouka_assistant.ai.navigationBarHeight
import cn.cjlmonster.hyouka_assistant.json.JTools


/**
 * BaseActivity
 *
 * @author cjl
 * @date 2025/6/22 14:42
 */
abstract class BaseActivity<B : ViewBinding> : AppCompatActivity() {

    protected lateinit var binding: B
    private lateinit var webView: WebView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        WKPlugin.addActivity(this)
        binding = createBinding()
        webView = bindWebView()
        setContentView(binding.root)
        addViewTreeObserver()
        initViewModel()
        initListener()
        initData()
    }

    override fun onDestroy() {
        removeViewTreeObserver()
        WKPlugin.removeActivity(this)
        super.onDestroy()
    }

    protected abstract fun createBinding(): B

    protected abstract fun bindWebView(): WebView

    protected abstract fun initViewModel()

    protected open fun initListener() {}

    protected open fun initData() {}

    fun callMethod(id: Int, method: String, callback: String, extras: Map<*, *>? = null) {
        runOnUiThread {
            WKPlugin.callMethod(hashCode(), id, method, callback, extras)
        }
    }

    fun onFlutterCallback(id: Int, method: String, callback: String, data: Map<*, *>) {
        Log.i(
            WKPlugin.TAG,
            "onFlutterCallback -> id: $id, method: $method, callback: $callback, data: ${
                JTools.toJson(data)
            }"
        )
        webView.evaluate(id, callback, data)
    }

    fun onRecognizeReceived(data: Map<*, *>) {
        val callback = "onRecognizeReceived"
        webView.evaluateJavascript("$callback(${JTools.toJson(data)})", null)
    }

    private var isPlayingAnime = false

    private fun addViewTreeObserver() {
        webView.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener)
    }

    private fun removeViewTreeObserver() {
        webView.viewTreeObserver.removeOnGlobalLayoutListener(onGlobalLayoutListener)
    }

    /**
     * 监听键盘弹出和收起
     */
    private val onGlobalLayoutListener = OnGlobalLayoutListener {
        if (isPlayingAnime) return@OnGlobalLayoutListener
        val r = Rect()
        // 获取当前窗口可视区域
        webView.getWindowVisibleDisplayFrame(r)
        // 屏幕总高度
        val screenHeight = webView.getRootView().height
        // 键盘高度 = 屏幕高度 - 可视区域高度
        val keypadHeight = screenHeight - r.bottom - navigationBarHeight
        val param = webView.layoutParams as MarginLayoutParams
        Log.i(
            TAG,
            "onGlobalLayoutListener: bottomMargin = ${param.bottomMargin}, keypadHeight = $keypadHeight, navigationBarHeight = $navigationBarHeight"
        )
        if (param.bottomMargin != keypadHeight) {
            isPlayingAnime = true
            ValueAnimator.ofInt(param.bottomMargin, keypadHeight).run {
                duration = 200
                interpolator = DecelerateInterpolator()
                addUpdateListener {
                    param.bottomMargin = it.animatedValue as Int
                    webView.layoutParams = param
                }
                addListener(object : AnimatorListenerAdapter() {
                    override fun onAnimationEnd(animation: Animator) {
                        isPlayingAnime = false
                    }

                    override fun onAnimationCancel(animation: Animator) {
                        isPlayingAnime = false
                    }
                })
                start()
            }
        }
    }

}